﻿using System;

namespace Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrarySL
{
    public class BindingCollection
    {
        #region private variables

        private System.Collections.Generic.Dictionary<string, Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrarySL.Binding> m_BindingDictionary = new System.Collections.Generic.Dictionary<string, Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrarySL.Binding>();

        private Microsoft.CSA.FeedSync.FeedSyncLibrarySL.RSSFeed m_RSSFeed = null;

        #endregion

        public BindingCollection(Microsoft.CSA.FeedSync.FeedSyncLibrarySL.RSSFeed i_RSSFeed) :
            this(i_RSSFeed, true)
        {
        }

        public BindingCollection(Microsoft.CSA.FeedSync.FeedSyncLibrarySL.RSSFeed i_RSSFeed, bool i_CreateDefaultTitleDescription)
        {
            if (i_RSSFeed == null)
                throw new System.ArgumentException("i_RSSFeed must be non-null!");

            m_RSSFeed = i_RSSFeed;

            var BindingXElements = i_RSSFeed.ChannelXElement.Elements(Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrarySL.Constants.SimpleFeedBindingsXNamespace + Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrarySL.Constants.BINDING_ELEMENT_NAME);

            foreach (System.Xml.Linq.XElement BindingXElement in BindingXElements)
            {
                Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrarySL.Binding Binding = new Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrarySL.Binding
                    (
                    BindingXElement,
                    i_CreateDefaultTitleDescription
                    );

                this.AddBinding(Binding, false);
            }
        }

        public System.Collections.Generic.IList<Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrarySL.Binding> Bindings
        {
            get
            {
                return new System.Collections.Generic.List<Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrarySL.Binding>(m_BindingDictionary.Values);
            }
        }

        public bool HasBinding(string i_ID)
        {
            Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrarySL.Binding Binding = null;
            return (this.FindBinding(i_ID, out Binding));
        }

        public bool FindBinding(string i_ID, out Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrarySL.Binding o_Binding)
        {
            o_Binding = null;

            if (!m_BindingDictionary.ContainsKey(i_ID))
                return false;

            o_Binding = m_BindingDictionary[i_ID];

            return true;

        }

        public Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrarySL.Binding GetBinding(string i_ID)
        {
            Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrarySL.Binding Binding = null;

            if (!this.FindBinding(i_ID, out Binding))
                throw new System.ArgumentException("Invalid id: " + i_ID);

            return Binding; ;
        }

        public Microsoft.CSA.FeedSync.FeedSyncLibrarySL.RSSFeed RSSFeed
        {
            get
            {
                return m_RSSFeed;
            }

        }

        public void AddBinding(Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrarySL.Binding i_Binding, bool i_AppendXElement)
        {
            if (this.HasBinding(i_Binding.ID))
                throw new System.ArgumentException("Binding already exists!");

            if (i_Binding.XElement.Document != m_RSSFeed.XDocument)
            {
                System.Xml.Linq.XElement ImportedBindingXElement = new System.Xml.Linq.XElement(Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrarySL.Constants.FIELD_EXTENSION_ELEMENT_NAME);

                i_Binding = new Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrarySL.Binding
                    (
                    ImportedBindingXElement,
                    i_Binding.DefaultTitleDescription
                    );
            }

            m_BindingDictionary[i_Binding.ID] = i_Binding;

            i_Binding.BindingCollection = this;

            if (i_AppendXElement)
                m_RSSFeed.ChannelXElement.Add(i_Binding.XElement);
        }

        public void ReplaceBinding(string i_ID, Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrarySL.Binding i_Binding)
        {
            if (System.String.IsNullOrEmpty(i_ID))
                throw new System.ArgumentException("i_ID must be non-null!");

            if (i_Binding == null)
                throw new System.Exception("i_Binding must be non-null!");

            Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrarySL.Binding Binding;

            if (!this.FindBinding(i_ID, out Binding))
                throw new System.ArgumentException("Specified item does not exist!");

            Binding.XElement.Remove();

            if (i_Binding.XElement.Document != m_RSSFeed.XDocument)
            {
                System.Xml.Linq.XElement ClonedXElement = new System.Xml.Linq.XElement(i_Binding.XElement);

                i_Binding = new Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrarySL.Binding
                    (
                    ClonedXElement,
                    i_Binding.DefaultTitleDescription
                    );
            }

            m_RSSFeed.ChannelXElement.Add(i_Binding.XElement);

            m_BindingDictionary[i_ID] = i_Binding;
        }

        public System.Collections.Generic.IList<Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrarySL.Binding> GetMergeChangeList(Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrarySL.BindingCollection i_IncomingBindingCollection)
        {
            System.Collections.Generic.IList<Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrarySL.Binding> MergedBindingList = Microsoft.CSA.FeedSync.FeedSyncLibrarySL.Sync.Merge<Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrarySL.Binding>
                (
                this.Bindings,
                i_IncomingBindingCollection.Bindings
                );

            return MergedBindingList;
        }

        public void Merge(Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrarySL.BindingCollection i_IncomingBindingCollection)
        {
            System.Collections.Generic.IList<Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrarySL.Binding> MergedBindingList = this.GetMergeChangeList(i_IncomingBindingCollection);

            //  Merge collections
            foreach (Microsoft.CSA.FeedSync.SimpleFeedBindingsLibrarySL.Binding MergedBinding in MergedBindingList)
            {
                if (this.HasBinding(MergedBinding.Sync.ID))
                {
                    this.ReplaceBinding
                        (
                        MergedBinding.Sync.ID,
                        MergedBinding
                        );
                }
                else
                {
                    this.AddBinding
                        (
                        MergedBinding,
                        true
                        );
                }
            }
        }

    }
}
